~ chicken-core (master) /manual/Cross development
Trap1[[tags: manual]]2[[toc:]]345== Cross Development67Since CHICKEN generates C code, it is relatively easy to create8programs and libraries for a different architecture than the one the9compiler is executing on, a process commonly called ''cross10compiling''. Basically you can simply compile Scheme code to C and11then invoke your target-specific cross compiler. To automate the12process of invoking the correct C compiler with the correct settings13and to simplify the use of extensions, CHICKEN can be built in a14special "cross-compilation" mode.1516Note: in the following text we refer to the "target" as being the17platform on which the software is intended to run in the end. We use18the term "host" as the system that builds this software. Others use a19different nomenclature or switch the meaning of the words.2021=== Preparations2223Make sure you have a cross-toolchain in your {{PATH}}. In this24example, a Linux system is used to generate binaries for an ARM based25embedded system.2627==== Building the target libraries2829First you need a version of the runtime system ({{libchicken}}),30compiled for the target system. Obtain and unpack a tarball of the31CHICKEN sources, or check out the code from the official code32repository, then build the libraries and necessary development files:3334 make ARCH= \35 PREFIX=/usr \36 PLATFORM=linux \37 HOSTSYSTEM=arm-none-linux-gnueabi \38 DESTDIR=$HOME/target \39 TARGET_FEATURES="-no-feature x86 -feature arm" \40 install4142This will build CHICKEN and install it in {{~/target}}, which we use43as a temporary place to store the target files. A few things to note:4445* {{ARCH}} is empty, since we don't want the build process to detect the architecture (since the target-architecture is likely to be different). If you know the right string to represent target architecture, you can set {{ARCH}} with that value. This string is passed to the {{-arch}} compiler and linker option for ios and sometimes conditionally checked in platform-specific makefiles)46* {{PREFIX}} gives the prefix ''on the target system'', under which the47libraries will finally be installed. In this case it will be {{/usr/lib}}.4849* {{PLATFORM}} determines the target platform. It must be one of the officially50supported platforms CHICKEN runs on. Note that it actually refer to the extension of a dedicated Makefile (`Makefile.linux` in our case).5152* {{HOSTSYSTEM}} is an identifier for the target system and will be used as53the name prefix of the cross C compiler (in this case {{arm-none-linux-gnueabi-gcc}}).54If your cross compiler does not follow this convention, pass {{C_COMPILER}} and55{{LIBRARIAN}} to the {{make(1)}} invocation, with the names of the C compiler and56{{ar(1)}} tool, respectively.5758* {{DESTDIR}} holds the directory where the compiled library files will temporarily59be installed into.6061* {{TARGET_FEATURES}} contains extra options to be passed to the target-specific62Scheme translator; in this case we disable and enable features so that code like63the following will do the right thing when cross-compiled:6465<enscript hightlight=scheme>66(cond-expand67 (x86 <do this ...>)68 ...)69</enscript>7071* If you obtained the sources from a source-code repository and not72from an official release tarball, you will need a {{chicken}}73executable to compile the Scheme sources of the runtime system. In74this case pass yet another variable to the {{make(1)}} invocation:75{{CHICKEN=<where the "chicken" executable is>}}.7677* You can also put all those variables into a file, say {{config.mk}}78and run {{make CONFIG=config.mk}}.7980You should now have these files on {{~/target}}:8182 |-- bin83 | |-- chicken84 | |-- chicken-bug85 | |-- chicken-install86 | |-- chicken-profile87 | |-- chicken-status88 | |-- chicken-uninstall89 | |-- csc90 | `-- csi91 |-- include92 | |-- chicken-config.h93 | `-- chicken.h94 |-- lib95 | |-- chicken96 | | `-- 997 | | :98 | |99 | |-- libchicken.a100 | |-- libchicken.so -> libchicken.so.9101 | `-- libchicken.so.9102 `-- share103 |-- chicken104 | |-- doc105 : ; :106 | |107 | `-- setup.defaults108 `-- man109 `-- man1110 :111112You should now transfer {{~/target/usr/lib}} to the target system, and place113its contents in {{/usr/lib}}. You may want to omit the static library {{libchicken.a}} if the target memory is limited.114115==== Building the "cross chicken"116117Next, we will build another chicken, one that uses the cross C compiler to118generate target-specific code that uses the target-specific runtime library119we have just built.120121Again, unpack a CHICKEN release tarball or a source tree and run122{{make(1)}} once again:123124 make PLATFORM=linux \125 PREFIX=$HOME/cross-chicken \126 TARGETSYSTEM=arm-none-linux-gnueabi \127 PROGRAM_PREFIX=arm- \128 TARGET_PREFIX=$HOME/target/usr \129 TARGET_RUN_PREFIX=/usr \130 install131132* {{PREFIX}} gives the place where the "cross chicken" should be installed133into. It is recommended not to install into a standard location (like {{/usr/local}}134or {{$HOME}}) - some files will conflict with a normal CHICKEN installation.135136* {{TARGETSYSTEM}} gives the name-prefix of the cross C compiler and other tools (C++ compiler, librarian (ar) and ressource compiler (for windows)).137138* {{PROGRAM_PREFIX}} determines the name-prefix of the CHICKEN tools to be created.139140* {{TARGET_PREFIX}} specifies where the target-specific files (libraries and141headers) are located. This is the location where we installed the runtime142system into.143144* {{TARGET_RUN_PREFIX}} holds the PREFIX that will be effective at runtime145(so {{libchicken.so}} will be found in {{$TARGET_RUN_PREFIX/lib}}).146147* Make sure to use the same version of the CHICKEN sources for the target and148the cross build.149150* If you build the cross chicken from repository sources, the same note151about the {{CHICKEN}} variable applies as given above.152153In {{~/cross-chicken}}, you should find the following:154155 |-- bin156 | |-- arm-chicken157 | |-- arm-chicken-install158 | |-- arm-chicken-profile159 | |-- arm-chicken-status160 | |-- arm-chicken-uninstall161 | |-- arm-csc162 | `-- arm-csi163 |-- include164 | |-- chicken-config.h165 | `-- chicken.h166 |-- lib167 | |-- chicken168 | | `-- 9169 | | :170 | |171 | |-- libchicken.a172 | |-- libchicken.so -> libchicken.so.9173 | `-- libchicken.so.9174 `-- share175 |-- chicken176 | |-- doc177 : ; :178 | |179 | `-- setup.defaults180 `-- man181 `-- man1182 :183184To make sure that the right C compiler is used, we ask {{arm-csc}} to show185the name of the cross C compiler:186187 % ~/cross-chicken/bin/arm-csc -cc-name188 arm-none-linux-gnueabi-gcc189190Looks good.191192==== Special notes for Linux to Windows cross development193194To cross compile from Linux to Windows, you will need to use a Linux build of MingGW-w64 with you can find in most distribution.195196As far as the runtime is concerned, the procedure is the same that what have been shown before, using the platform name {{cross-linux-mingw}}.197198The procedure to compile the compiler however require some more care:199* The platform name is {{linux}} because it is where you want your compiler to run200* You have to set the {{TARGET_LIBRARIES}} as this is different between Linux and Windows:201 For Linux target, this variable contains {{-ldl -lm}}, while for Windows target it should be {{-lm -lws2_32}}.202* You have to make sure you are pointing to the right toolchain (see next paragraph).203204In order to compile the C sources that Chicken will produce you have to make sure that you provide the right toolchain in both runtime and compiler steps.205206In most cases, you want to do that by setting {{HOSTSYSTEM}} when building the runtime and {{TARGETSYSTEM}} when building the compiler to something similar to {{x86_64-w64-mingw32}} (check you distribution binaries). For example:207208 # build a CHICKEN runtime for windows209 > make PREFIX=$HOME/target PLATFORM=cross-linux-mingw HOSTSYSTEM=x86_64-w64-mingw32 install210 > make confclean211 # build a CHICKEN cross-compiler that uses the runtime above212 > make PREFIX=$HOME/cross PROGRAM_PREFIX=mingw- TARGET_PREFIX=$HOME/target PLATFORM=linux TARGETSYSTEM=x86_64-w64-mingw32 TARGET_LIBRARIES="-lm -lws2_32" install213214If your distribution does not stick to the {{PREFIX-TOOLNAME}} convention you may want to set some following variables (runtime step/compiler step):215* {{C_COMPILER}}/{{TARGET_C_COMPILER}}216* {{CXX_COMPILER}}/{{TARGET_CXX_COMPILER}}217* {{LIBRARIAN}}/{{TARGET_LIBRARIAN}} for {{ar}}218* {{RC_COMPILER}}/{{TARGET_RC_COMPILER}} for {{windres}}219220You may need this trick to pick {{x86_64-w64-mingw32-gcc-posix}} over {{x86_64-w64-mingw32-gcc-win32}} in Debian for example (those correspond to different thread APIs).221222=== Using it223224==== Compiling simple programs225226 % ~/cross-chicken/bin/arm-csc -v hello.scm227 /home/felix/cross-chicken/arm-cross-chicken/bin/arm-chicken hello.scm -output-file hello.c -quiet228 arm-none-linux-gnueabi-gcc hello.c -o hello.o -c -fno-strict-aliasing -DHAVE_CHICKEN_CONFIG_H -g -Wall \229 -Wno-unused -I /home/felix/cross-chicken/arm-chicken/include230 rm hello.c231 arm-none-linux-gnueabi-gcc hello.o -o hello -L/home/felix/cross-chicken/arm-chicken/lib -Wl,-R/usr/lib -lm \232 -ldl -lchicken233 rm hello.o234235Is it an ARM binary?236237 % file hello238 hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.6.16, dynamically linked (uses shared libs), not stripped239240Yes, looks good.241242==== Compiling extensions243244By default, the tools that CHICKEN provides to install, list and uninstall245extensions will operate on both the host and the target repository.246So running {{arm-chicken-install}} will compile and install the extension247for the host system and for the cross-target. To selectively install, uninstall248or list extensions for either the host or the target system use the249{{-host}} and {{-target}} options for the tools.250251For example, using the mingw-cross-compiler from above, we can create252a standalone Windows exe file that includes the CHICKEN runtime and all253egg dependencies.254255 # install an egg using the mingw cross compiler above256 > $HOME/cross/bin/mingw-chicken-install fmt257 > cat hello.scm258 (import fmt chicken.platform)259 (fmt #t "hello world from " (software-type) nl260 (pretty (features)))261 # create a standalone exe file with the CHICKEN and fmt statically linked262 > $HOME/cross/bin/mingw-csc -static hello.scm263 # hello.exe should now run on Window without any runtime DLL dependencies:264 > x86_64-w64-mingw32-objdump -p hello.exe | grep "DLL Name"265 DLL Name: KERNEL32.dll266 DLL Name: msvcrt.dll267 DLL Name: USER32.dll268 DLL Name: WS2_32.dll269 # or using wine270 > wine hello.exe271 hello world from windows272 (#:windows #:64bit #:cross-chicken273 #:ptables #:dload #:little-endian274 #:x86-64 #:gnu #:mingw32275 ...)276277278=== "Target-only" extensions279280Sometimes an extension will only be compilable for the target platform281(for example libraries that use system-dependent features). In this282case you will have to work around the problem that the host-compiler283still may need compile-time information from the target-only284extension, like the import library of modules. One option is to copy285the import-library source file into the repository of the host compiler:286287 # optionally, you can compile the import library:288 # ~/cross-chicken/bin/arm-csc -O3 -d0 -s target-only-extension.import.scm289 cp target-only-extension.import.scm ~/cross-chicken/lib/chicken/9290291=== Final notes292293Cross-development is a very tricky process - it often involves countless294manual steps and it is very easy to forget an important detail or mix295up target and host systems. Also, full 100% platform neutrality is296hard to achieve. CHICKEN tries very hard to make this transparent, but297at the price of considerable complexity in the code that manages298extensions.299300301----302Previous: [[Deployment]]303304Next: [[Bugs and limitations]]